#ifndef __SHELL_H__
#define __SHELL_H__

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "list.h"
#include "lock.h"
#include "wait.h"
#include "log.h"

#include <strings.h>
#include <readline/readline.h>
#include <readline/history.h>

#define MAX_PARAM_NUMS      256

typedef struct {
    char *name;            /* User printable name of the function. */
    rl_icpfunc_t *func;        /* Function to call to do the job. */
    char *doc;            /* Documentation for this function. */
}shell_command_t;

typedef struct {
    int param_nums;
    char* cmd;//char cmd[32];
    char* param[MAX_PARAM_NUMS];//char param[128];
}cmd_object_t;

enum SHELL_COMMAND
{
    SHELL_COMMAND_SWITCH = 0,
    SHELL_COMMAND_MAX,
};

struct shell;

enum SHELL_EVENT
{
    SHELL_EVENT_NONE = 0,
    SHELL_EVENT_COMMANDS,
    SHELL_EVENT_MAX,
};

typedef int32_t (*shell_event_notify)(struct shell*, int32_t, void*, void*);

struct shell_event_action
{
    shell_event_notify notify;
    void* object;
    struct shell_event_action* next;
};

struct shell_operation
{
    int32_t (*init)(struct shell*);
    int32_t (*release)(struct shell*);
    
    int32_t (*process)(struct shell*);

    int32_t (*register_notify)(struct shell*, int32_t, shell_event_notify notify, void*);
    int32_t (*unregister_notify)(struct shell*, int32_t, void*);
    int32_t (*trigger_notify)(struct shell*, int32_t, void*);
};

struct shell
{
    struct list_head head;
    wait_t wait;
    lock_t lock;
    lock_t notify_lock;

    int running_flag;
    pthread_t pid;

    struct shell_operation* op;
    struct shell_event_action *paction[SHELL_EVENT_MAX];
};

int32_t create_init_shell(struct shell** pshell);
void release_destroy_shell(struct shell* pshell);
        
#endif
